package naito_rescue.router.object;

import java.io.*;
import java.util.*;
import rescuecore2.worldmodel.EntityID;
import naito_rescue.*;

public class AdaptiveSearchNode implements Comparable<AdaptiveSearchNode>
{
	protected AdaptiveSearchNode parent = null;
	protected int counter;
	protected int updatedHeuristic = Integer.MIN_VALUE;
	protected boolean isUpdated = false;
    protected int pathLength;
    protected int heuristicValue;
    protected EntityID nodeID;
    protected EntityID goal;
	protected MyLogger logger;    
	public AdaptiveSearchNode(EntityID nodeID, EntityID goal, AdaptiveSearchNode parent, 
							int distanceToParent, int heuristicValue, int count, MyLogger logger){
        if (parent != null)
        {
            this.pathLength = parent.pathLength;
        }
        else
        {
            this.pathLength = 0;
        }
        this.nodeID = nodeID;
        this.parent = parent;
        this.pathLength += distanceToParent;
        this.heuristicValue = heuristicValue;
		this.goal = goal;
		this.counter = count;
		this.updatedHeuristic = 0;
		this.isUpdated = false; //防衛的プログラミングのようなもの
		this.logger = logger;
	}
    public int getPathLength()
    {
        return pathLength;
    }

    public int getHeuristicValue()
    {
        return heuristicValue;
    }

    public EntityID getNodeID()
    {
        return nodeID;
    }

	public int getCounter(){
		return this.counter;
	}
	public EntityID getGoalID(){
		return this.goal;
	}
	public int getUpdatedHeuristic(){
		return this.updatedHeuristic;
	}
	public boolean isUpdatedHeuristic(){
		return this.isUpdated;
	}
	public void updateHeuristicValue(int minCost){
		//-- デバッグログ --
		int oldH = -1;
		if(isUpdated){
			oldH = this.updatedHeuristic;
		}else{
			oldH = this.heuristicValue;
		}
		//logger.trace("AdaptiveSearchNode(" + nodeID.getValue() + "),oldHeuristic=" + oldH + ",newHeuristic=" + (minCost - this.pathLength), "AdaptiveSearchNode#updateHeuristicValue");
		this.updatedHeuristic = minCost - this.pathLength;
		//isUpdated = true; //ヒューリスティックの値に，更新した値を使う
	}
	public AdaptiveSearchNode getParent(){
		return this.parent;
	}
	
	@Override
	public int compareTo(AdaptiveSearchNode other){
		// 更新されたヒューリスティックを利用するように書く
		int myEstimatedCost, otherEstimatedCost;
		/*
		if(isUpdated) 
			myEstimatedCost = (this.pathLength + this.updatedHeuristic);
		else
			myEstimatedCost = (this.pathLength + this.heuristicValue);
		if(other.isUpdatedHeuristic())
			otherEstimatedCost = (other.getPathLength() + other.getUpdatedHeuristic());
		else
			otherEstimatedCost = (other.getPathLength() + other.heuristicValue);
		*/
		myEstimatedCost = (this.pathLength + this.heuristicValue);
		otherEstimatedCost = (other.getPathLength() + other.heuristicValue);
		return myEstimatedCost - otherEstimatedCost;
	}
	@Override
	public String toString(){
		StringBuffer sb = new StringBuffer();
		
		sb.append("AdaptiveSearchNode(" + this.nodeID.getValue());
		sb.append(",g:" + goal.getValue());
		sb.append(",c:" + counter);
		sb.append(",h:" + heuristicValue);
		sb.append(",uh:" + updatedHeuristic + ")");
		return sb.toString();
	}
}
